(本篇文章網誌版:http://shineright.blogspot.tw/2016/12/day-12.html)
今天要使裝備發射昨天完成的子彈。
新增一個名為「SpawnBullet.cs」的C# Script。
public class SpawnBullet : MonoBehaviour
{
public GameObject bulletPrefab; //子彈Prefab
public float interval; //兩發子彈之間的時間
public bool followMovement; //子彈是否隨角色移動而移動
void Start()
{
StartCoroutine (SpawnCoroutine ());
}
IEnumerator SpawnCoroutine()
{
while (true) {
//產生子彈
GameObject bullet = (Instantiate (bulletPrefab, new Vector3(transform.position.x, transform.position.y, 0.1f), Quaternion.identity) as GameObject);
//如果要隨主角移動,把子彈設為裝備的子物件
if (followMovement)
bullet.transform.parent = transform;
//等候下一發子彈的時間
yield return new WaitForSeconds (interval);
}
}
}
bulletPrefab
和interval
分別用來儲存子彈的Prefab以及兩次發射之間的時間。followMovement
讓我可以在Inspector選擇子彈是否隨主角移動而移動。死亡之帽、竹蜻蜓、皮卡耳、雷達的子彈不會隨主角移動而移動,但綠帽、爆炸頭會。
SpawnCoroutine
中,我以Instantiate
生產新的子彈。把Z軸設為0.1f是為了讓子彈出現在裝備後面(影響較大的只有「綠帽」這個裝備,要使綠光在綠帽後面)。接著我判斷是否要讓子彈followMovement
,如果是,則把它的parent設為裝備。因為裝備是主角的子物件,所以如果把子彈設為裝備的子物件,主角移物時裝備會跟著移動,子彈也會跟著裝備移動。最後,我以yield return new WaitForSeconds(interval)
來等待下一發子彈的發射時間。
回到Unity Editor,在Hierarchy欄把上次做的四種子彈拖到Project欄,成為Prefab。再到四種裝備的Prefab新增Spawn Bullet (Script) Component,把子彈的Prefab拖到Bullet Prefab欄,設好Interval。進入Play Mode測試,子彈射擊的座標不太正確,所以我用Day 8的方式,把位置不對的子彈包在一個空的Game Object裡,使之成為新的子彈Prefab,再調整內部實際子彈的位置。
接著來處理綠帽和爆炸頭。這兩種子彈的做法其實和之前的子彈差不多。將它們的Sprite拖至Scene,用新的Game Object包裝以調整座標,再拉到Project成為Prefab。
我想要讓綠帽的綠光子彈有從半透明閃爍的效果,所以到Animation視窗新增動畫。點擊左方的Add Property→Sprite Renderer→Color可在時間軸上調整Color.a,也就是透明度。
在綠帽和爆炸頭的裝備Prefab上,一樣新增Spawn Bullet (Script) Component,把剛剛做好的綠光和爆炸頭子彈Prefab拉到Bullet Prefab欄,設好Interval。為了讓它們跟隨角色移動,把Follow Movement欄打勾。
進入Play Mode測試,現在綠光和爆炸頭子彈確實會跟著主角移動而移動,然而,發射出的子彈永遠不會消失,所以時間一久,主角便會被成千上萬的綠光罩頂。回去看先前做的所有子彈,一旦發射出去,便永遠存留在Hierarchy欄,不會消失。這和先前掉落裝備的問題一樣,物件離開螢幕卻沒有被真正移除。我要用一與掉落裝備不同的方式來處理這個問題,因為綠光和爆炸頭不會離開螢幕,所以不能用Collider來偵測它們何時該消失。
建立一個名為「DestroyAfterSeconds.cs」的C# Script。
public class DestroyAfterSeconds : MonoBehaviour
{
//過幾秒後移除Game Object
public float second;
void Start()
{
//second秒後呼叫DestroyGameObject函數
Invoke ("DestroyGameObject", second);
}
void DestroyGameObject()
{
Destroy (gameObject);
}
}
這段程式碼相當簡單,second
代表要移除Game Object的時間。Start
函數中,我呼叫了Invoke()
函數。Invoke(string methodName, float time)
函數會在time
秒後呼叫名為methodName
的函數。所以這段程式碼中,它會在second
秒後呼叫DestroyGameObject
函數,而DestroyGameObject
函數會呼叫Destroy(gameObject)
把自身移除。
把Destroy After Seconds (Script) Component加到每個子彈上,並為它們設定要消失的時間。死亡之帽、竹蜻蜓、雷達、皮卡耳應把Second設定為所有子彈都離開螢幕的時間,避免子彈在螢幕上突然消失。而爆炸頭、綠帽應把Second設定為小於裝備Interval的時間,避免同時出現兩道綠光或爆炸頭子彈。
進入Play Mode測試一下,完美。
終於把每個角色的側身像畫完了,耶!
待續。